使用 MVC 建置員工通訊錄列表範例 (預設有資料庫)
前置作業
開發環境: Visual Studio 或其他支援 ASP.NET Core MVC 的 IDE。
資料庫: SQL Server、MySQL 或其他你熟悉的資料庫。
Entity Framework Core: 用於與資料庫互動的 ORM 工具。
建立 MVC 專案
開啟 Visual Studio,建立一個新的 ASP.NET Core MVC 專案。
選擇模板: 選擇 "MVC" 模板,並根據需求選擇其他選項(如身份驗證、資料庫等)。
建立資料模型
建立實體類別:
C#
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
}
請謹慎使用程式碼。
設定資料庫上下文:
C#
public class EmployeeContext : DbContext
{
public EmployeeContext(DbContextOptions options)
: base(options)
{
}
public DbSet<Empl
oyee> Employees { get; set; }
}
請謹慎使用程式碼。
{
"ConnectionStrings": {
"EmployeeContext": "YourConnectionString"
}
}
請謹慎使用程式碼。
#public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<EmployeeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("EmployeeContext")));
// ...其他服務註冊
}與直接寫builder.services.AddDbContext<EmployeeContext>(options =>
options.UseSqlServer(connString)); 的差別~
關於在不同位置註冊 EmployeeContext 的詳細比較
為什麼會有兩種寫法?
這兩種寫法主要出現在不同的 ASP.NET Core 版本和架構中:
Startup.cs 中的 ConfigureServices: 這是傳統 ASP.NET Core 應用程式中配置服務的標準方式。
Program.cs 中的 builder.Services.AddDbContext: 出現於 ASP.NET Core 6.0+ 的 Minimal API 中,提供了一種更簡潔的配置方式。
兩種寫法的差異與優缺點
特徵 Startup.cs (傳統) Program.cs (Minimal API)
位置 Startup.cs 檔案 Program.cs 檔案
方式 services.AddDbContext builder.Services.AddDbContext
優點 - 集中管理服務配置<br>- 適合中大型應用程式<br>- 更好的可擴展性 - 簡潔、快速配置<br>- 適合小型應用程式
缺點 - 程式碼相對較多<br>- 對於小型應用程式可能過於繁瑣 - 缺乏集中管理<br>- 可擴展性相對較弱
何時使用哪種寫法?
傳統 ASP.NET Core 應用程式: 建議使用 Startup.cs 中的 ConfigureServices,因為它提供了更好的結構和可維護性,特別是對於中大型應用程式。
Minimal API: 如果你的應用程式比較簡單,並且希望快速搭建,可以使用 Program.cs 中的 builder.Services.AddDbContext。
直接在 Program.cs 中寫 builder.services.AddDbContext 可以嗎?
答案是可以的,對於小型 Minimal API 應用程式來說,這種寫法完全可行。但是,你需要注意以下幾點:
簡化配置: 如果你的應用程式比較簡單,並且不需要過多的服務配置,那麼直接在 Program.cs 中註冊 DbContext 可以簡化開發流程。
可維護性: 對於較大的應用程式,將所有服務配置集中在 Startup.cs 中可以提高程式碼的可讀性和可維護性。
擴展性: 如果你的應用程式需要進行大量的服務配置,那麼 Startup.cs 提供了更靈活的擴展機制。
---
為什麼將服務配置集中在 Startup.cs 中可以提高可維護性和擴展性?
可維護性
集中管理,一目瞭然:
所有服務的註冊都在 Startup.cs 中集中管理,當需要修改或新增服務時,開發人員可以直接在這個檔案中找到對應的程式碼,無需在整個專案中搜索。
這種集中式的管理方式,使得程式碼的結構更加清晰,更容易理解。
降低耦合度:
將服務配置與其他業務邏輯分離,降低了不同部分程式碼之間的耦合度。
當需要修改某個服務的配置時,只需要修改 Startup.cs 中的相關程式碼,而不會影響到其他部分的邏輯。
方便測試:
透過依賴注入,可以輕鬆地替換服務的實現,方便進行單元測試。
擴展性
靈活的擴展機制:
Startup.cs 提供了豐富的擴展點,例如 ConfigureServices、Configure 等方法,可以根據需要自定義應用程式的行為。
可以通過繼承 Startup 類別或實現自定義中間件來擴展應用程式的功能。
支援多種配置方式:
Startup.cs 可以從多種配置源讀取設定,例如 appsettings.json、環境變數、命令列參數等。
這使得應用程式可以根據不同的環境進行配置,提高了靈活性。
範例示範
假設我們有一個 ASP.NET Core Web API 應用程式,需要註冊以下服務:
DbContext:用於連接資料庫
ILoggerFactory:用於記錄日誌
IMailService:用於發送郵件
在 Startup.cs 中,我們可以這樣配置:
C#
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionSt
ring("MyDatabase")));
services.Add
Logging(loggingBuilder =>
{
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
});
services.AddScoped<IMailService, EmailService>();
services.AddControllers();
}
請謹慎使用程式碼。
如果需要新增一個新的服務(例如,一個緩存服務),我們只需要在 ConfigureServices 方法中添加一行程式碼即可:
C#
services.AddMemoryCache();
請謹慎使用程式碼。
如果需要修改資料庫連接字串,只需要修改 appsettings.json 檔案中的配置即可。
---
建立控制器
C#
public class EmployeesController : Controller
{
private readonly EmployeeContext _context;
public EmployeesController(EmployeeContext conte
xt)
{
_context = context;
}
public IActionResult
Index()
{
var employees = _context.Employees.ToList();
return View(employees);
}
}
請謹慎使用程式碼。
建立檢視
建立 Views/Employees/Index.cshtml 檢視:
Razor CSHTML
@model IEnumerable<Mvc7_Fundamentals.Models.Employee>
@{
ViewData["Title"] = "員工通訊錄";
}
@{
ViewData["Title"] = "員工通訊錄";
}
同時增加排序和搜尋功能
當您需要在 ASP.NET Core MVC 應用程式中同時實現排序和搜尋功能時,可以結合前面所提到的 ViewModel 和 LINQ to Entities 的方式,來達成更複雜的查詢。
在 ViewModel 中新增 SortOrder 屬性,用來儲存排序的欄位名稱和排序方式。
修改 Controller
C#
public IActionResult Index(EmployeeSearchViewModel model)
{
var employees = _context.Employees.AsQueryable();
if (!string.IsNullOrEmpty(model.SearchTerm))
{
employees = employees.Where(e =>
e.Name.Contains(model.SearchTerm) ||
e.Email.Contains(model.SearchTerm) ||
e.PhoneNumber.Contains(model.SearchTerm)
);
}
switch (model.SortOrder)
{
case "name_desc":
employees = employees.OrderByDescending(s => s.Name);
break;
case "email_asc":
employees = employees.OrderBy(s => s.Email);
break;
// ... 其他排序條件
default:
employees = employees.OrderBy(s => s.Name);
break;
}
model.Employees = employees.ToList();
return View(model);
}
請謹慎使用程式碼。
在 Controller 中,根據 SearchTerm 和 SortOrder 來篩選和排序資料。
在 View 中,新增一個下拉式選單,讓使用者選擇排序方式。
完整範例
C#
//public class HomeController : Controller
{
private readonly MyDbContext _context;
public HomeController(MyDbContext context)
{
_context = context;
}
public IActionResult Index(EmployeeSearchViewModel model)
{
var employees = _context.Employees.AsQueryable();
// 搜尋
if (!string.IsNullOrEmpty(model.SearchTerm))
{
employees = employees.Where(e =>
e.Name.Contains(model.SearchTerm) ||
e.Email.Contains(model.SearchTerm) ||
e.PhoneNumber.Contains(model.SearchTerm)
);
}
// 排序
switch (model.SortOrder)
{
case "name_asc":
employees = employees.OrderBy(s => s.Name);
break;
case "name_desc":
employees = employees.OrderByDescending(s => s.Name);
break;
case "email_asc":
employees = employees.OrderBy(s => s.Email);
break;
case "email_desc":
employees = employees.OrderByDescending(s => s.Email);
break;
case "phone_asc":
employees = employees.OrderBy(s => s.PhoneNumber);
break;
case "phone_desc":
employees = employees.OrderByDescending(s => s.PhoneNumber);
break;
default:
employees = employees.OrderBy(s => s.Name);
break;
}
model.Employees = employees.ToList();
return View(model);
}
}